﻿using System;
using System.Collections.Generic;
using System.Text;

using System.Runtime.InteropServices;
using System.Drawing;
using System.Drawing.Imaging;

namespace BadApplePlayer
{
    public class ImageHelper
    {
        private static System.IO.StreamWriter g_writer = new System.IO.StreamWriter("Log.log");

        public static Bitmap MixLineImage(Bitmap bmpSrc, Bitmap bmpBack, Color backColor, Color lineColor) {
            DateTime dt = DateTime.Now;
            Bitmap bmp = new Bitmap(bmpBack.Width, bmpBack.Height, PixelFormat.Format32bppArgb);
            using (Bitmap bmpTemp = new Bitmap(bmpSrc.Width, bmpSrc.Height, PixelFormat.Format32bppArgb)) {
                using (SolidBrush sb = new SolidBrush(backColor)) {
                    using (Graphics g = Graphics.FromImage(bmpTemp)) {
                        g.FillRectangle(sb, 0, 0, bmpTemp.Width, bmpTemp.Height);
                    }
                }
                BitmapData bmpDataSrc = bmpSrc.LockBits(new Rectangle(0, 0, bmpTemp.Width, bmpTemp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
                byte[] byColorInfoSrc = new byte[bmpTemp.Height * bmpDataSrc.Stride];
                Marshal.Copy(bmpDataSrc.Scan0, byColorInfoSrc, 0, byColorInfoSrc.Length);
                BitmapData bmpData = bmpTemp.LockBits(new Rectangle(0, 0, bmpTemp.Width, bmpTemp.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
                byte[] byColorInfo = new byte[byColorInfoSrc.Length];
                Marshal.Copy(bmpData.Scan0, byColorInfo, 0, byColorInfo.Length);
                for (int x = 0, xLen = bmpTemp.Width - 1; x < xLen; x++) {
                    for (int y = 0, yLen = bmpTemp.Height - 1; y < yLen; y++) {
                        int indexB = y * bmpDataSrc.Stride + x * 4;
                        int indexG = y * bmpDataSrc.Stride + x * 4 + 1;
                        int indexR = y * bmpDataSrc.Stride + x * 4 + 2;
                        byte byV = (byte)(GetAvg(
                            byColorInfoSrc[indexB],
                            byColorInfoSrc[indexG],
                            byColorInfoSrc[indexR]) > 95 ? 255 : 0);
                        byte byVR = (byte)(GetAvg(
                            byColorInfoSrc[indexB + 4],
                            byColorInfoSrc[indexG + 4],
                            byColorInfoSrc[indexR + 4]) > 95 ? 255 : 0);
                        //byte byVRB = (byte)(GetAvg(
                        //    byColorInfoSrc[(y + 1) * bmpDataSrc.Stride + (x + 1) * 4],
                        //    byColorInfoSrc[(y + 1) * bmpDataSrc.Stride + (x + 1) * 4 + 1],
                        //    byColorInfoSrc[(y + 1) * bmpDataSrc.Stride + (x + 1) * 4 + 2]) > 127 ? 255 : 0);
                        byte byVB = (byte)(GetAvg(
                            byColorInfoSrc[indexB + bmpDataSrc.Stride],
                            byColorInfoSrc[indexG + bmpDataSrc.Stride],
                            byColorInfoSrc[indexR + bmpDataSrc.Stride]) > 95 ? 255 : 0);
                        //if (byV != byVRB) {
                        //    byColorInfo[y * bmpData.Stride + x * 4] =
                        //    byColorInfo[y * bmpData.Stride + x * 4 + 1] =
                        //    byColorInfo[y * bmpData.Stride + x * 4 + 2] =
                        //    byColorInfo[y * bmpData.Stride + (x + 1) * 4] =
                        //    byColorInfo[y * bmpData.Stride + (x + 1) * 4 + 1] =
                        //    byColorInfo[y * bmpData.Stride + (x + 1) * 4 + 2] =
                        //    byColorInfo[(y + 1) * bmpData.Stride + (x + 1) * 4] =
                        //    byColorInfo[(y + 1) * bmpData.Stride + (x + 1) * 4 + 1] =
                        //    byColorInfo[(y + 1) * bmpData.Stride + (x + 1) * 4 + 2] =
                        //    byColorInfo[(y + 1) * bmpData.Stride + x * 4] =
                        //    byColorInfo[(y + 1) * bmpData.Stride + x * 4 + 1] =
                        //    byColorInfo[(y + 1) * bmpData.Stride + x * 4 + 2] = 125;
                        //    continue;
                        //}
                        if (byV != byVR) {
                            byColorInfo[indexB] = lineColor.B;
                            byColorInfo[indexG] = lineColor.G;
                            byColorInfo[indexR] = lineColor.R;
                            byColorInfo[indexR + 1] = lineColor.A;
                            //byColorInfo[y * bmpData.Stride + (x + 1) * 4] = 255;
                            //byColorInfo[y * bmpData.Stride + (x + 1) * 4 + 1] = 144;
                            //byColorInfo[y * bmpData.Stride + (x + 1) * 4 + 2] = 41;
                        }
                        if (byV != byVB) {
                            byColorInfo[indexB] = lineColor.B;
                            byColorInfo[indexG] = lineColor.G;
                            byColorInfo[indexR] = lineColor.R;
                            byColorInfo[indexR + 1] = lineColor.A;
                            //byColorInfo[(y + 1) * bmpData.Stride + x * 4] = 255;
                            //byColorInfo[(y + 1) * bmpData.Stride + x * 4 + 1] = 144;
                            //byColorInfo[(y + 1) * bmpData.Stride + x * 4 + 2] = 41;
                        }
                    }
                }
                Marshal.Copy(byColorInfoSrc, 0, bmpDataSrc.Scan0, byColorInfoSrc.Length);
                bmpSrc.UnlockBits(bmpDataSrc);
                Marshal.Copy(byColorInfo, 0, bmpData.Scan0, byColorInfo.Length);
                bmpTemp.UnlockBits(bmpData);
                using (Graphics g = Graphics.FromImage(bmp)) {
                    g.DrawImage(bmpBack, 0, 0);
                    g.DrawImage(bmpTemp, new Rectangle(Point.Empty, bmpBack.Size), new Rectangle(Point.Empty, bmpTemp.Size), GraphicsUnit.Pixel);
                }
            }
            g_writer.WriteLine(DateTime.Now.Subtract(dt).TotalMilliseconds);
            g_writer.Flush();
            return bmp;
        }
        private static byte GetAvg(byte b, byte g, byte r) {
            return (byte)((r + g + b) >> 2);
        }
    }
}
